package com.spring.AOP;

import com.spring.AOP.AopAnnotation.After;
import com.spring.AOP.AopAnnotation.Around;
import com.spring.AOP.AopAnnotation.Before;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class PointCutMatcher {
    public boolean matches(Method method, String pointcutExpression) {
        try {
            Class<?> annotationClass = Class.forName(pointcutExpression);
            if (annotationClass.isAnnotation()) {
                return method.isAnnotationPresent((Class) annotationClass);
            }
        } catch (ClassNotFoundException e) {
            System.err.println("切点表达式解析失败: " + pointcutExpression);
        }
        return false;
    }
    public List<MethodInfo> matchAndCollectMethods(List< Method> methods, Set<String> pointcutExpressions) {
        return methods.stream()
                .filter(method -> pointcutExpressions.stream()
                        .anyMatch(pointcutExpression -> matches(method, pointcutExpression)))
                .map(method -> new MethodInfo(method.getName(), method.getParameters(), method.getParameterTypes()))
                .collect(Collectors.toList());
    }

    public boolean matches(Method adviceMethod, Method targetMethod) {
        String pointcutExpression = getPointcutExpression(adviceMethod);
        return !pointcutExpression.isEmpty() && matches(targetMethod, pointcutExpression);
    }

    public String getPointcutExpression(Method adviceMethod) {
        // 解析不同类型通知的切点表达式
        if (adviceMethod.isAnnotationPresent(Before.class)) {
            return adviceMethod.getAnnotation(Before.class).value();
        } else if (adviceMethod.isAnnotationPresent(After.class)) {
            return adviceMethod.getAnnotation(After.class).value();
        } else if (adviceMethod.isAnnotationPresent(Around.class)) {
            return adviceMethod.getAnnotation(Around.class).value();
        }
        return "";
    }
}
